use std::future::{ready, Ready};
use crate::config::jwt::validate_jwt;
use actix_web::{body::EitherBody, dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform}, Error, HttpResponse};
use actix_web::web::Json;
use futures_util::{future::LocalBoxFuture, FutureExt as _, TryFutureExt as _};
use crate::config::api::R;

// 这里定义你的认证服务
pub struct AuthMiddleware<S> {
    service: S,
}

impl<S, B> Service<ServiceRequest> for AuthMiddleware<S>
where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
    S::Future: 'static,
    B: 'static,
{
    type Response = ServiceResponse<EitherBody<B>>;
    type Error = Error;
    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;

    forward_ready!(service);

    fn call(&self, req: ServiceRequest) -> Self::Future {
        log::info!("Checking if request is authorized");

        // 示例: 从请求头获取“Authorization”来检查凭证，这里需要替换成你的认证逻辑
        if let Some(auth_header) = req.headers().get("Authorization") {
            if let Ok(auth_str) = auth_header.to_str() {
                // 检验auth_str，比如是否是有效的JWT
                if is_authorized(auth_str) {
                    // 如果认证通过，继续执行
                    return self
                        .service
                        .call(req)
                        .map_ok(ServiceResponse::map_into_left_body)
                        .boxed_local();
                }
            }
        }
        // 认证失败，返回错误响应
        return Box::pin(async {
            let res: Json<R<String>> = Json(R::error(400, &String::from("请先登录")));
            Ok(req.into_response(HttpResponse::Unauthorized().json(res).map_into_right_body()))
        });
    }
}

// 这里定义认证转换器
#[derive(Clone, Debug)]
pub struct Authenticate;

impl<S, B> Transform<S, ServiceRequest> for Authenticate
where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
    S::Future: 'static,
    B: 'static,
{
    type Response = ServiceResponse<EitherBody<B>>;
    type Error = Error;
    type Transform = AuthMiddleware<S>;
    type InitError = ();
    type Future = Ready<Result<Self::Transform, Self::InitError>>;

    fn new_transform(&self, service: S) -> Self::Future {
        ready(Ok(AuthMiddleware { service }))
    }
}

// 示例：这是个示例函数，你需要替换成你自己的认证逻辑
fn is_authorized(auth_header: &str) -> bool {
    // 实现你的认证逻辑，例如JWT验证
    // 返回true如果认证成功，否则false
    validate_jwt(auth_header).is_ok()
}
